/*
 * Copyright © 2017 camunda services GmbH (info@camunda.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.camunda.zeebe.protocol;

import static io.camunda.zeebe.protocol.ColumnFamilyScope.GLOBAL;
import static io.camunda.zeebe.protocol.ColumnFamilyScope.PARTITION_LOCAL;

public enum ZbColumnFamilies implements EnumValue, ScopedColumnFamily {
  DEFAULT(0, PARTITION_LOCAL),

  // util
  KEY(1, PARTITION_LOCAL),

  // process
  @Deprecated
  DEPRECATED_PROCESS_VERSION(2, GLOBAL),

  // process cache
  @Deprecated
  DEPRECATED_PROCESS_CACHE(3, GLOBAL),
  @Deprecated
  DEPRECATED_PROCESS_CACHE_BY_ID_AND_VERSION(4, GLOBAL),
  @Deprecated
  DEPRECATED_PROCESS_CACHE_DIGEST_BY_ID(5, GLOBAL),

  // element instance
  ELEMENT_INSTANCE_PARENT_CHILD(6, PARTITION_LOCAL),
  ELEMENT_INSTANCE_KEY(7, PARTITION_LOCAL),

  NUMBER_OF_TAKEN_SEQUENCE_FLOWS(8, PARTITION_LOCAL),

  // variable state
  ELEMENT_INSTANCE_CHILD_PARENT(9, PARTITION_LOCAL),
  VARIABLES(10, PARTITION_LOCAL),
  @Deprecated
  TEMPORARY_VARIABLE_STORE(11, PARTITION_LOCAL),

  // timer state
  TIMERS(12, PARTITION_LOCAL),
  TIMER_DUE_DATES(13, PARTITION_LOCAL),

  // pending deployments
  PENDING_DEPLOYMENT(14, PARTITION_LOCAL),
  DEPLOYMENT_RAW(15, PARTITION_LOCAL),

  // jobs
  JOBS(16, PARTITION_LOCAL),
  JOB_STATES(17, PARTITION_LOCAL),
  JOB_DEADLINES(18, PARTITION_LOCAL),
  @Deprecated
  DEPRECATED_JOB_ACTIVATABLE(19, PARTITION_LOCAL),

  // message
  MESSAGE_KEY(20, PARTITION_LOCAL),
  @Deprecated
  DEPRECATED_MESSAGES(21, PARTITION_LOCAL),
  MESSAGE_DEADLINES(22, PARTITION_LOCAL),
  MESSAGE_IDS(23, PARTITION_LOCAL),
  MESSAGE_CORRELATED(24, PARTITION_LOCAL),
  MESSAGE_PROCESSES_ACTIVE_BY_CORRELATION_KEY(25, PARTITION_LOCAL),
  MESSAGE_PROCESS_INSTANCE_CORRELATION_KEYS(26, PARTITION_LOCAL),

  // message subscription
  MESSAGE_SUBSCRIPTION_BY_KEY(27, PARTITION_LOCAL),
  @Deprecated // only used for migration logic
  MESSAGE_SUBSCRIPTION_BY_SENT_TIME(28, PARTITION_LOCAL),
  // migration end
  @Deprecated
  DEPRECATED_MESSAGE_SUBSCRIPTION_BY_NAME_AND_CORRELATION_KEY(29, PARTITION_LOCAL),

  // message start event subscription
  @Deprecated
  DEPRECATED_MESSAGE_START_EVENT_SUBSCRIPTION_BY_NAME_AND_KEY(30, PARTITION_LOCAL),
  @Deprecated
  DEPRECATED_MESSAGE_START_EVENT_SUBSCRIPTION_BY_KEY_AND_NAME(31, PARTITION_LOCAL),

  // process message subscription
  @Deprecated
  DEPRECATED_PROCESS_SUBSCRIPTION_BY_KEY(32, PARTITION_LOCAL),
  // migration start
  @Deprecated // only used for migration logic
  PROCESS_SUBSCRIPTION_BY_SENT_TIME(33, PARTITION_LOCAL),
  // migration end

  // incident
  INCIDENTS(34, PARTITION_LOCAL),
  INCIDENT_PROCESS_INSTANCES(35, PARTITION_LOCAL),
  INCIDENT_JOBS(36, PARTITION_LOCAL),

  // event
  EVENT_SCOPE(37, PARTITION_LOCAL),
  EVENT_TRIGGER(38, PARTITION_LOCAL),

  BANNED_INSTANCE(39, PARTITION_LOCAL),

  EXPORTER(40, PARTITION_LOCAL),

  AWAIT_WORKLOW_RESULT(41, PARTITION_LOCAL),

  JOB_BACKOFF(42, PARTITION_LOCAL),

  @Deprecated
  DEPRECATED_DMN_DECISIONS(43, GLOBAL),
  @Deprecated
  DEPRECATED_DMN_DECISION_REQUIREMENTS(44, GLOBAL),
  @Deprecated
  DEPRECATED_DMN_LATEST_DECISION_BY_ID(45, GLOBAL),
  @Deprecated
  DEPRECATED_DMN_LATEST_DECISION_REQUIREMENTS_BY_ID(46, GLOBAL),
  @Deprecated
  DEPRECATED_DMN_DECISION_KEY_BY_DECISION_REQUIREMENTS_KEY(47, GLOBAL),
  @Deprecated
  DEPRECATED_DMN_DECISION_KEY_BY_DECISION_ID_AND_VERSION(48, GLOBAL),
  @Deprecated
  DEPRECATED_DMN_DECISION_REQUIREMENTS_KEY_BY_DECISION_REQUIREMENT_ID_AND_VERSION(49, GLOBAL),

  // signal subscription
  @Deprecated
  DEPRECATED_SIGNAL_SUBSCRIPTION_BY_NAME_AND_KEY(50, GLOBAL),
  @Deprecated
  DEPRECATED_SIGNAL_SUBSCRIPTION_BY_KEY_AND_NAME(51, GLOBAL),

  // distribution
  PENDING_DISTRIBUTION(52, PARTITION_LOCAL),
  COMMAND_DISTRIBUTION_RECORD(53, PARTITION_LOCAL),
  MESSAGE_STATS(54, PARTITION_LOCAL),

  PROCESS_INSTANCE_KEY_BY_DEFINITION_KEY(55, PARTITION_LOCAL),

  MIGRATIONS_STATE(56, GLOBAL),

  PROCESS_VERSION(57, GLOBAL),
  PROCESS_CACHE(58, GLOBAL),
  PROCESS_CACHE_BY_ID_AND_VERSION(59, GLOBAL),
  PROCESS_CACHE_DIGEST_BY_ID(60, GLOBAL),

  DMN_DECISIONS(61, GLOBAL),
  DMN_DECISION_REQUIREMENTS(62, GLOBAL),
  DMN_LATEST_DECISION_BY_ID(63, GLOBAL),
  DMN_LATEST_DECISION_REQUIREMENTS_BY_ID(64, GLOBAL),
  DMN_DECISION_KEY_BY_DECISION_REQUIREMENTS_KEY(65, GLOBAL),
  DMN_DECISION_KEY_BY_DECISION_ID_AND_VERSION(66, GLOBAL),
  DMN_DECISION_REQUIREMENTS_KEY_BY_DECISION_REQUIREMENT_ID_AND_VERSION(67, GLOBAL),

  FORMS(68, GLOBAL),
  FORM_VERSION(69, GLOBAL),
  FORM_BY_ID_AND_VERSION(70, GLOBAL),

  MESSAGES(71, PARTITION_LOCAL),
  MESSAGE_START_EVENT_SUBSCRIPTION_BY_NAME_AND_KEY(72, PARTITION_LOCAL),
  MESSAGE_START_EVENT_SUBSCRIPTION_BY_KEY_AND_NAME(73, PARTITION_LOCAL),
  MESSAGE_SUBSCRIPTION_BY_NAME_AND_CORRELATION_KEY(74, PARTITION_LOCAL),
  PROCESS_SUBSCRIPTION_BY_KEY(75, PARTITION_LOCAL),

  JOB_ACTIVATABLE(76, PARTITION_LOCAL),

  SIGNAL_SUBSCRIPTION_BY_NAME_AND_KEY(77, PARTITION_LOCAL),
  SIGNAL_SUBSCRIPTION_BY_KEY_AND_NAME(78, PARTITION_LOCAL),

  USER_TASKS(79, PARTITION_LOCAL),
  USER_TASK_STATES(80, PARTITION_LOCAL),
  COMPENSATION_SUBSCRIPTION(81, PARTITION_LOCAL),

  PROCESS_DEFINITION_KEY_BY_PROCESS_ID_AND_DEPLOYMENT_KEY(82, GLOBAL),
  DMN_DECISION_KEY_BY_DECISION_ID_AND_DEPLOYMENT_KEY(83, GLOBAL),
  FORM_KEY_BY_FORM_ID_AND_DEPLOYMENT_KEY(84, GLOBAL),

  MESSAGE_CORRELATION(85, PARTITION_LOCAL),

  USERS(86, GLOBAL),
  @Deprecated
  USER_KEY_BY_USERNAME(87, GLOBAL),

  CLOCK(88, GLOBAL),

  AUTHORIZATIONS(89, GLOBAL),
  PERMISSIONS(90, GLOBAL),

  PROCESS_DEFINITION_KEY_BY_PROCESS_ID_AND_VERSION_TAG(91, GLOBAL),
  DMN_DECISION_KEY_BY_DECISION_ID_AND_VERSION_TAG(92, GLOBAL),
  FORM_KEY_BY_FORM_ID_AND_VERSION_TAG(93, GLOBAL),

  @Deprecated
  AUTHORIZATION_KEY_BY_RESOURCE_ID(94, GLOBAL),
  @Deprecated
  OWNER_TYPE_BY_OWNER_KEY(95, GLOBAL),

  ROUTING(96, GLOBAL),

  QUEUED_DISTRIBUTION(97, PARTITION_LOCAL),
  RETRIABLE_DISTRIBUTION(98, PARTITION_LOCAL),
  DISTRIBUTION_CONTINUATION(99, PARTITION_LOCAL),

  RESOURCES(100, GLOBAL),
  RESOURCE_VERSION(101, GLOBAL),
  RESOURCE_BY_ID_AND_VERSION(102, GLOBAL),
  RESOURCE_KEY_BY_RESOURCE_ID_AND_VERSION_TAG(103, GLOBAL),
  RESOURCE_KEY_BY_RESOURCE_ID_AND_DEPLOYMENT_KEY(104, GLOBAL),

  ROLES(105, GLOBAL),

  TENANTS(106, GLOBAL),

  USER_TASK_INTERMEDIATE_STATES(107, PARTITION_LOCAL),

  MAPPINGS(108, GLOBAL),

  ASYNC_REQUEST_METADATA(109, PARTITION_LOCAL),

  GROUPS(110, GLOBAL),

  @Deprecated
  REDISTRIBUTION(111, PARTITION_LOCAL),

  USERNAME_BY_USER_KEY(112, GLOBAL),
  CLAIM_BY_ID(113, GLOBAL),
  AUTHORIZATION_KEYS_BY_OWNER(114, GLOBAL),

  BATCH_OPERATION(115, PARTITION_LOCAL),
  PENDING_BATCH_OPERATION(116, PARTITION_LOCAL),
  BATCH_OPERATION_CHUNKS(117, PARTITION_LOCAL),

  VARIABLE_DOCUMENT_STATE_BY_SCOPE_KEY(118, PARTITION_LOCAL),

  RELATIONS_BY_ENTITY(119, GLOBAL),
  ENTITIES_BY_RELATION(120, GLOBAL),

  USER_TASK_INITIAL_ASSIGNEE(121, PARTITION_LOCAL),

  USAGE_METRICS(122, PARTITION_LOCAL),
  BOOTSTRAPPED_AT(123, GLOBAL),

  RUNTIME_INSTRUCTIONS(124, PARTITION_LOCAL);

  private final int value;
  private final ColumnFamilyScope columnFamilyScope;

  /**
   * @param value the value of the column family, which is used to identify it in the database
   * @param columnFamilyScope the scope of the column family, which determines whether it is global
   *     or partition-local:
   *     <ul>
   *       <li>{@link ColumnFamilyScope#GLOBAL} - the column family is global and shared across all
   *           partitions: when new partitions are created, they will be sent to the newly created
   *           partitions.
   *           <p>Examples: Process definitions, DMN decisions, forms, users, roles, tenants, etc.
   *       <li>{@link ColumnFamilyScope#PARTITION_LOCAL} - the column family is partition-local and
   *           only exists in the partition it was created in: when new partitions are created, they
   *           will not be sent to the newly created partitions.
   *           <p>Examples: Element instances, variables, jobs, messages, timers, incidents, etc.
   *     </ul>
   *     NOTE: The correct {@link ColumnFamilyScope} is crucial for the correctness of dynamic
   *     scaling partitions.
   */
  ZbColumnFamilies(final int value, final ColumnFamilyScope columnFamilyScope) {
    this.value = value;
    this.columnFamilyScope = columnFamilyScope;
  }

  @Override
  public int getValue() {
    return value;
  }

  @Override
  public ColumnFamilyScope partitionScope() {
    return columnFamilyScope;
  }
}
